//
//  DateUtility.h
//  ToHow
//
//  Created by maple on 14-5-6.
//  Copyright (c) 2014年 maple. All rights reserved.
// 日期类的方法集合

#define DAY_OF_SECONDS 24*60*60

#define DEFAULT_DATE_TEMPLATE_STRING @"yyyy-MM-dd HH:mm:ss"
#define DEFAULT_SHORT_DATE_TEMPLATE_STRING @"yyyy-MM-dd HH:mm"
#define SHORT_DATE_TEMPLATE_STRING @"yyyy-MM-dd"
#define HOUR_MINUT_TEMPLATE_STRING @"HH:mm"
#define DETAIL_DATE_TEMPLATE_STRING @"yyyy年MM月dd日"
#define MONTH_DATE_TEMPLATE_STRING @"yyyy-MM"

struct MNSDate {
    NSUInteger second;
    NSUInteger minute;
    NSUInteger hour;
    NSUInteger weekday;
    NSUInteger day;
    NSUInteger month;
    NSUInteger year;
};
typedef struct MNSDate MNSDate;

/**
 * 描述：将日期转化为MNSDate对象
 * 参数：要转化的日期
 * 返回值：MNSDate值，可以跟对象属性获取相应的年，月，日，时，分，秒
 *
 */
CG_INLINE MNSDate MNSDateMake(NSDate *date) {
    MNSDate MNSDate;
    
    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSSecondCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:date];
    
    MNSDate.second = [components second];
    MNSDate.minute = [components minute];
    MNSDate.hour = [components hour];
    MNSDate.weekday = [components weekday];
    MNSDate.day = [components day];
    MNSDate.month = [components month];
    MNSDate.year = [components year];
    
    return MNSDate;
}


/**
 * 描述：获取从fromdate开始，经过天后的日期
 * 参数：fromDate：开始日期   dayGap：天数
 * 返回值：计算后的日期
 *
 */
CG_INLINE NSDate * getDate(NSDate *fromDate, NSInteger dayGap) {
    return [NSDate dateWithTimeInterval:DAY_OF_SECONDS * dayGap sinceDate:fromDate];
}

/**
 * 描述：获取从fromdate开始，经过时间戳的日期
 * 参数：fromDate：开始日期   timeGap：时间戳
 * 返回值：计算后的日期
 *
 */
CG_INLINE NSDate * getTimeIntevalDate(NSDate *fromDate, NSTimeInterval timeGap) {
    return [NSDate dateWithTimeInterval:timeGap sinceDate:fromDate];
}


/**
 * 描述：获取当前的本地日期
 * 参数：时间
 * 返回值：本地日期
 *
 */
CG_INLINE NSDate * getLocalDateFromGMTDate(NSDate *GMTDate) {
    NSTimeZone *zone = [NSTimeZone systemTimeZone];
    
    NSInteger interval = [zone secondsFromGMTForDate: GMTDate];
    
    NSDate *localeDate = [GMTDate  dateByAddingTimeInterval: interval];
    
    return localeDate;
}

/**
 * 描述：获取当前的月最后一天的日期
 * 参数：月份
 * 返回值：当前的月最后一天的日期
 *
 */
CG_INLINE NSDate * getLastDateOfMonth(NSDate *targetMonthDay) {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSRange daysRange = [calendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:targetMonthDay];
    
    NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:targetMonthDay];
    [components setDay:daysRange.length];
    
    return [calendar dateFromComponents:components];
}

/**
 * 描述：获取当前的月第一天的日期
 * 参数：月份
 * 返回值：当前的月第一天的日期
 *
 */
CG_INLINE NSDate * getFirstDateOfMonth(NSDate *targetMonthDay) {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:targetMonthDay];
    [components setDay:1];
    
    return [calendar dateFromComponents:components];
}

/**
 * 描述：获取一周第一天的日期
 * 参数：日期
 * 返回值：一周第一天的日期
 *
 */
CG_INLINE NSDate *getFirstDateOfWeek(NSDate *date) {
    MNSDate MNSDate = MNSDateMake(date);
    
    return getDate(date, -1 * (MNSDate.weekday - 1));
}

/**
 * 描述：获取明天日期
 * 参数：日期
 * 返回值：明天的日期
 *
 */
CG_INLINE NSDate *getTomorrowDate() {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSDate *today = [NSDate date];
    
    NSDateComponents *components = [calendar components:kCFCalendarUnitHour | kCFCalendarUnitMinute | kCFCalendarUnitSecond fromDate:today];
    NSInteger hour = [components hour];
    NSInteger minute = [components minute];
    NSInteger second = [components second];
    
    NSTimeInterval timeInterval = DAY_OF_SECONDS - 3600 * hour - 60 * minute - second + 1;
    
    return [NSDate dateWithTimeInterval:timeInterval sinceDate:today];;
}

/**
 * 描述：获取今天日期
 * 参数：日期
 * 返回值：今天的日期
 *
 */
CG_INLINE NSDate *getTodayDate() {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSDate *today = [NSDate date];
    
    NSDateComponents *components = [calendar components:kCFCalendarUnitHour | kCFCalendarUnitMinute | kCFCalendarUnitSecond fromDate:today];
    NSInteger hour = [components hour];
    NSInteger minute = [components minute];
    NSInteger second = [components second];
    
    NSTimeInterval timeInterval = 0 - 3600 * hour - 60 * minute - second;
    
    return [NSDate dateWithTimeInterval:timeInterval sinceDate:today];;
}


/**
 * 描述：获取昨天日期
 * 参数：日期
 * 返回值：昨天的日期
 *
 */
CG_INLINE NSDate *getYesterdayDate() {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSDate *today = [NSDate date];
    
    NSDateComponents *components = [calendar components:kCFCalendarUnitHour | kCFCalendarUnitMinute | kCFCalendarUnitSecond fromDate:today];
    NSInteger hour = [components hour];
    NSInteger minute = [components minute];
    NSInteger second = [components second];
    
    NSTimeInterval timeInterval = 0 - 3600 * hour - 60 * minute - second - 1;
    
    return [NSDate dateWithTimeInterval:timeInterval sinceDate:today];
}


/**
 * 描述：获取日期
 * 参数：dateVariationCount  与现在天数的差距数
 * 返回值：日期
 *
 */
CG_INLINE NSDate *getDateVariation(NSTimeInterval dateVariationCount){
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSDate *today = [NSDate date];
    
    NSDateComponents *components = [calendar components:kCFCalendarUnitHour | kCFCalendarUnitMinute | kCFCalendarUnitSecond fromDate:today];
    NSInteger hour = [components hour];
    NSInteger minute = [components minute];
    NSInteger second = [components second];
    
    NSTimeInterval timeInterval = 0.0f;
    if (dateVariationCount>0) {
        timeInterval = dateVariationCount*DAY_OF_SECONDS - 3600 * hour - 60 * minute - second + 1;
    }else if(dateVariationCount<0){
        timeInterval = 0 - 3600 * hour - 60 * minute - second - 1- (0-(dateVariationCount+1))*DAY_OF_SECONDS;
    }
    return [NSDate dateWithTimeInterval:timeInterval sinceDate:today];
}




/**
 * 描述: 将日期字符串按格式转化为nsdate对象
 * 参数：dateStringTemplate：日期格式（如:YY-MM-DD）  dateStr:日期的字符串表达
 * 返回值：转化后的nsdate对象
 *
 */
CG_INLINE NSDate * getDateFromString(NSString *dateStringTemplate, NSString *dateStr) {
    [NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehavior10_4];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    
    if (!dateStringTemplate) {
        dateStringTemplate = DEFAULT_DATE_TEMPLATE_STRING;
    }
    
    [dateFormatter setDateFormat:dateStringTemplate];
    
    NSDate *date = [dateFormatter dateFromString:dateStr];
    
    return date;
}

/**
 * 描述: 将nsdate对象按格式转化为字符串
 * 参数：dateStringTemplate：日期格式（如:YY-MM-DD）  date:nsdate对象
 * 返回值：转化后的字符串对象
 *
 */
CG_INLINE NSString *getStringFromDate(NSString *dateStringTemplate, NSDate *date) {
    [NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehavior10_4];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    
    if (!dateStringTemplate) {
        dateStringTemplate = DEFAULT_DATE_TEMPLATE_STRING;
    }
    
    [dateFormatter setDateFormat:dateStringTemplate];
    MNSDate msDate = MNSDateMake(date);
    
    NSString *dateStr = [dateFormatter stringFromDate:date];
    
    return dateStr;
}

//根据点数获取时间
CG_INLINE NSDate *getHourDate(int hour){
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSDate *today = [NSDate date];
    
    NSDateComponents *components = [calendar components:kCFCalendarUnitHour | kCFCalendarUnitMinute | kCFCalendarUnitSecond fromDate:today];
    NSInteger comHour = [components hour];
    NSInteger minute = [components minute];
    NSInteger second = [components second];
    
    NSTimeInterval timeInterval = 0.0f;
    
    timeInterval = 0 - 3600 * comHour - 60 * minute - second;
    NSDate *newDate = [NSDate dateWithTimeInterval:timeInterval+hour*3600 sinceDate:today];
    return newDate;

}

CG_INLINE NSString *convertDateUnit(int unit){
    if (unit<10) {
        return [NSString stringWithFormat:@"0%i",unit];
    }
    return [NSString stringWithFormat:@"%i",unit];
}


//格式化日期
CG_INLINE NSString *convertStringFromNowDate(NSDate *convertDate){
    
    NSDate *date = [NSDate date];
    MNSDate mnsDate = MNSDateMake(date);
    MNSDate mnsConvDate = MNSDateMake(convertDate);
    
    if (mnsDate.year==mnsDate.year) {
        if (mnsDate.month==mnsDate.month) {
            if (mnsDate.day==mnsDate.day) {
                return [NSString stringWithFormat:@"%@:%@:%@",convertDateUnit(mnsConvDate.hour),convertDateUnit(mnsConvDate.minute),convertDateUnit(mnsConvDate.second)];
            }else{
                if (mnsDate.day==(mnsConvDate.day+1)) {
                    return @"昨天";
                }
                return [NSString stringWithFormat:@"%@-%@",convertDateUnit(mnsConvDate.month),convertDateUnit(mnsConvDate.day)];
            }
        }else{
            return [NSString stringWithFormat:@"%@-%@",convertDateUnit(mnsConvDate.month),convertDateUnit(mnsConvDate.day)];
        }
    }else{
        return [NSString stringWithFormat:@"%@-%@-%@",convertDateUnit(mnsConvDate.year),convertDateUnit(mnsConvDate.month),convertDateUnit(mnsConvDate.day)];
    }
    return @"";
}


CG_INLINE NSString *convertTimeStringFromNowDate(NSDate *convertDate){
    
    NSDate *date = [NSDate date];
    MNSDate mnsDate = MNSDateMake(date);
    MNSDate mnsConvDate = MNSDateMake(convertDate);
    
    if (mnsDate.year==mnsDate.year) {
        if (mnsDate.month==mnsDate.month) {
            if (mnsDate.day==mnsDate.day) {
                return [NSString stringWithFormat:@"%@:%@",convertDateUnit(mnsConvDate.hour),convertDateUnit(mnsConvDate.minute)];
            }else{
                if (mnsDate.day==(mnsConvDate.day+1)) {
                    return @"昨天";
                }
                return [NSString stringWithFormat:@"%@-%@",convertDateUnit(mnsConvDate.month),convertDateUnit(mnsConvDate.day)];
            }
        }else{
            return [NSString stringWithFormat:@"%@-%@",convertDateUnit(mnsConvDate.month),convertDateUnit(mnsConvDate.day)];
        }
    }else{
        return [NSString stringWithFormat:@"%@-%@-%@",convertDateUnit(mnsConvDate.year),convertDateUnit(mnsConvDate.month),convertDateUnit(mnsConvDate.day)];
    }
    return @"";
}

//获取日期的周
CG_INLINE NSString *convertWeekStringFromDate(NSDate *convertDate){
    NSArray * arrWeek=[NSArray arrayWithObjects:@"周日",@"周一",@"周二",@"周三",@"周四",@"周五",@"周六", nil];
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    NSInteger unitFlags = NSYearCalendarUnit |
    NSMonthCalendarUnit |
    NSDayCalendarUnit |
    NSWeekdayCalendarUnit |
    NSHourCalendarUnit |
    NSMinuteCalendarUnit |
    NSSecondCalendarUnit;
    comps = [calendar components:unitFlags fromDate:convertDate];
    int week = [comps weekday];
    return [arrWeek objectAtIndex:week-1];
}


//获取日期的星期
CG_INLINE NSString *convertDetailWeekStringFromDate(NSDate *convertDate){
    NSArray * arrWeek=[NSArray arrayWithObjects:@"星期日",@"星期一",@"星期二",@"星期三",@"星期四",@"星期五",@"星期六", nil];
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    NSInteger unitFlags = NSYearCalendarUnit |
    NSMonthCalendarUnit |
    NSDayCalendarUnit |
    NSWeekdayCalendarUnit |
    NSHourCalendarUnit |
    NSMinuteCalendarUnit |
    NSSecondCalendarUnit;
    comps = [calendar components:unitFlags fromDate:convertDate];
    int week = [comps weekday];
    return [arrWeek objectAtIndex:week-1];
}


